#!usr/bin/python
import sys

from django.utils import simplejson
from operator import itemgetter
from xml.dom import minidom

class ParseMovieFeed():
    def __init__(self, xmldom, filterDateStr):
        self.xmldom = xmldom
        self.theaters = []
        self.showtimes = {}
        self.movies = []
        self.moviesToTheaters = {}
        self.filterDateStr = filterDateStr
        
    def parse(self):
        theaterNodes = self.xmldom.getElementsByTagName("theater")
        showtimeNodes = self.xmldom.getElementsByTagName("showTime")
        movieNodes = self.xmldom.getElementsByTagName("movie")
        
        self.handleTheaterNodes(theaterNodes)
        self.handleShowtimeNodes(showtimeNodes)
        self.handleMovieNodes(movieNodes)
        
    def handleTheaterNodes(self, theaterNodes):
        for theaterNode in theaterNodes:
            self.handleTheaterNode(theaterNode)
            
    def handleTheaterNode(self, theaterNode):
        theaters_temp = {'tid':theaterNode.getAttribute('theaterId'),
                         'n':str(theaterNode.getElementsByTagName('name')[0].firstChild.data),
                         's':str(theaterNode.getElementsByTagName('street')[0].firstChild.data),
                         'c':str(theaterNode.getElementsByTagName('city')[0].firstChild.data),
                         'st':str(theaterNode.getElementsByTagName('state')[0].firstChild.data),
                         'p':str(theaterNode.getElementsByTagName('postalCode')[0].firstChild.data),
                         't':str(theaterNode.getElementsByTagName('telephone')[0].firstChild.data),
                         'lon':float(theaterNode.getElementsByTagName('longitude')[0].firstChild.data),
                         'lat':float(theaterNode.getElementsByTagName('latitude')[0].firstChild.data)
                        }
        
        self.theaters.append(theaters_temp)
        
    def handleShowtimeNodes(self, showtimeNodes):
        for showtimeNode in showtimeNodes:
            self.handleShowtimeNode(showtimeNode)
            
    def handleShowtimeNode(self, showtimeNode):
        nodeDate = int(showtimeNode.getAttribute('date'))
        if str(nodeDate) == self.filterDateStr:
            showtimes_temp = {}
            
            theaterID = int(showtimeNode.getAttribute('theaterId'))
            movieID = int(showtimeNode.getAttribute('movieId'))
            tIDmID = str(theaterID) + '|' + str(movieID)
            showtimes_temp[nodeDate] = []
            self.moviesToTheaters.setdefault(movieID, []).append(theaterID)
            
            timeNodes = showtimeNode.getElementsByTagName('time')
            for timeNode in timeNodes:
                showtime = list(str(timeNode.firstChild.data))
                showtime.insert(2, ':')
                showtimes_temp[nodeDate].append(''.join(showtime))
                
            self.showtimes[tIDmID] = showtimes_temp

    def handleMovieNodes(self, movieNodes):
        for movieNode in movieNodes:
            self.handleMovieNode(movieNode)
            
    def handleMovieNode(self, movieNode):
        movies_temp = {'g':[], 'a':[]}
              
        movies_temp['mid'] = int(movieNode.getAttribute('movieId'))
        movies_temp['t'] = str(movieNode.getElementsByTagName('officialTitle')[0].firstChild.data)
        movies_temp['m'] = int(movieNode.getElementsByTagName('runningTime')[0].firstChild.data)
        movies_temp['c'] = str(movieNode.getElementsByTagName('rating')[0].getAttribute('code'))
        movies_temp['l'] = str(movieNode.getElementsByTagName('originalLanguage')[0].firstChild.data)
        
        genreNodes = movieNode.getElementsByTagName('genre')
        for genreNode in genreNodes:
            movies_temp['g'].append(str(genreNode.firstChild.data))
        
        actorNodes = movieNode.getElementsByTagName('actor')
        for actorNode in actorNodes:
            actorName = str(actorNode.getElementsByTagName('firstName')[0].firstChild.data)
            movies_temp['a'].append(actorName)
            
        self.movies.append(movies_temp)    
        
    def sortMoviesByName(self):
        out = sorted(self.movies, key=itemgetter('t'));
        self.movies = out
    
    def cleanMoviesToTheatersList(self):
        cleanList = {}
        for m, t in self.moviesToTheaters.iteritems():
            t_set = set(t)
            t_list = list(t_set)
            t_list.sort()
            cleanList[m] = t_list
            
        self.moviesToTheaters = cleanList
                
    def getJSON(self):
        self.sortMoviesByName()
        self.cleanMoviesToTheatersList()
        struct = {'m':self.movies, 
                  's':self.showtimes, 
                  't':self.theaters, 
                  'mt':self.moviesToTheaters}
        json = simplejson.dumps(struct)
        
        #compress the JSON string
        json = json.replace(': ', ':')
        json = json.replace(', "', ',"')
        json = json.replace(', {', ',{')
        return json
             

def main(file_in, file_out):
  f = open(file_in, 'r')
  xmldom = minidom.parse(f)
  parser = ParseMovieFeed(xmldom)
  parser.parse()
  
  fo = open(file_out, 'w')
  fo.write(parser.getJSON())
  fo.close()


#entry point    
if __name__ == '__main__':
  args = sys.argv[1:]
  if len(args) == 2:
    file_in = args[0]
    file_out = args[1]
    main(file_in, file_out)
  else:
      print 'Usage: xml2json.py inputfile outputfile'